# 导入相关库
import numpy as np  # 导入numpy库，用于处理数组和数值计算
import matplotlib.pyplot as plt  # 导入matplotlib的绘图模块，用于可视化
plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
def chart_boxplot(box1,url=None,sample=[600,30],stdn=[1,2,3]):
    plt.figure(figsize=(9, 10.5), dpi=100)
    plt.subplot(3, 1, 1)
    # axes[0].figure(figsize=(9, 3.5), dpi=200)
    plt.plot(box1)
    # plt.suptitle()
    plt.title('时序图')
    # axes[1].figure(figsize=(9, 3.5), dpi=200)
    ax1=plt.subplot(3, 1, 2)
    if sample:
        box1.hist(bins=100,label="全部")
        for i in sample:
            box2=box1[-i:]
            box2.hist(bins=100,label="最近"+str(i))
        plt.legend()
    else:
        box1.hist(bins=100)
    plt.title('频率分布')
    # 计算箱图的第一四分位数（Q1）和第三四分位数（Q3）
    q1 = np.quantile(box1, .25)
    q3 = np.quantile(box1, .75)
    # 计算四分位距（IQR）
    iqr = q3 - q1
    # 计算箱图的上下边界（通常用于识别异常值）
    lower_boundary = q1 - 1.5 * iqr
    upper_boundary = q3 + 1.5 * iqr
    # 对随机数数组进行排序
    sort = np.sort(box1)
    # 定义用于标记不同统计量的颜色
    colors = ['#6b2983', '#5f82cb', '#00d6ff',
              '#e77ca3', '#93003a']
    ax2=plt.subplot(3, 1, 3)
    plt.title('离散分布')
    # 设置绘图的大小和分辨率
    # plt.figure(figsize=(9, 3.5), dpi=200)
    # 绘制箱图，这里设置箱图为水平方向
    if sample:
        box2=[box1]
        lables=["全部"]
        for i in sample:
            lables.append("最近"+str(i))
            box2.append(box1[-i:])
        plt.boxplot(box2, vert=False,labels=lables)
    else:
        plt.boxplot(box1, vert=False)
    # 使用散点图标记每个随机数的位置，颜色为红色，透明度为0.4
    plt.scatter(box1, np.linspace(1.3, 1.3, box1.shape[0]), color='r', alpha=.4, label='密度')
    # 使用垂直线标记箱图的上下边界、最小值、次小值（除去最小值）、最大值和异常值
    plt.vlines(lower_boundary, ymin=0.2, ymax=.65, alpha=1, ls='-.', color='k', label='Q1-1.5IQR')
    # plt.vlines(sort[0], ymin=0.2, ymax=.65, ls='-', lw=1.25, color=colors[2], label='最小值')
    # plt.vlines(sort[-2], ymin=0.2, ymax=.65, ls='-', lw=1.25, color=colors[3], label='最大值')
    plt.vlines(np.median(box1), ymin=0.2, ymax=.65, ls='-', lw=1.25, color="b", label='中位数',alpha=.5,)
    plt.vlines(np.mean(box1), ymin=0.2, ymax=.65, ls='-', lw=1.25, color="k", label='平均值',alpha=.5,)
    plt.vlines(sort[-1], ymin=0.2, ymax=.65, ls='-', lw=1.25, color=colors[4], label='异常值',alpha=.5,)
    plt.vlines(upper_boundary, ymin=0.2, ymax=.65, alpha=.5, ls='--', color='k', label='Q3+1.5IQR')
    plt.annotate(np.round(lower_boundary, 2), xy=(lower_boundary, 0.7), ha='center', color='k')
    plt.annotate(np.round(sort[0], 2), xy=(sort[0], 0.7), ha='center', color=colors[2])
    plt.annotate(np.round(sort[-2], 2), xy=(sort[-2], 0.7), ha='center', color=colors[3])
    plt.annotate(np.round(sort[-1], 2), xy=(sort[-1], 0.7), ha='center', color=colors[4])
    plt.annotate(np.round(upper_boundary, 2), xy=(upper_boundary, 0.8), ha='center', color='k')
    # 设置x轴的范围相同
    ax1.set_xlim(ax2.get_xlim())
    # ax1.set_xticks(ax2.get_xticks())
    # 显示图例，并将其放置在图的右上角
    plt.legend()
    if url is None:
        # 显示图表
        plt.show()
    else:
        plt.savefig(url, bbox_inches='tight', pad_inches=0.01, dpi=100)
        plt.close()